<script setup lang="ts">
import { reactive, onMounted, ref, computed, watch, defineAsyncComponent } from 'vue';
import {
  CalendarOptions,
  CalendarApi,
  // DateSelectArg,
  EventClickArg,
  ViewMountArg,
} from '@fullcalendar/core';
import FullCalendar from '@fullcalendar/vue3';
// 日期视图插件
import dayGridPlugin from '@fullcalendar/daygrid';
// 时间视图插件
import timeGridPlugin from '@fullcalendar/timegrid';
// 日程视图插件
import listGridPlugin from '@fullcalendar/list';
// 事件交互插件
import interactionPlugin from '@fullcalendar/interaction';
// 中文语言包
import zhCN from '@fullcalendar/core/locales/zh-cn';
// 英语语言包
import enGB from '@fullcalendar/core/locales/en-gb';
import * as d3 from 'd3';
import { mock_API } from '@/apis';
import useTestCalendarStore from '@/stores/modules/testCalendar';
const testCalendarStore = useTestCalendarStore();
const timeFormat = d3.timeFormat('%Y-%m-%d %H:%M:%S');
const { getEventList, delEvent } = mock_API;

// fullCalendar日历组件配置项
const calendarOptions = reactive<CalendarOptions>({
  plugins: [dayGridPlugin, timeGridPlugin, listGridPlugin, interactionPlugin],
  headerToolbar: false, // 工具栏  false表示自定义工具栏
  initialView: 'dayGridMonth', // 默认视图
  events: testCalendarStore.events, // 事件对象数组
  locale: zhCN, // 语言本地化
  timeZone: 'Asia/Shanghai',
  aspectRatio: devicePixelRatio > 2 ? 2 : devicePixelRatio, // 宽高比
  weekends: false, // 包含周六日
  selectable: false, // 日历上是否开启可选
  businessHours: true,
  // weekNumbers: true, // 在日历上显示周数
  // select: handleDateSelect, // 日历上鼠标选择时间回调
  eventClick: handleEventClick, // 点击日历上的事件对象回调
  viewDidMount: viewDidMount, // 视图加载完成的回调
  dayMaxEventRows: 3, // 控制一天当中最大的日程展示数目  超过该数目会进行折叠
});

function viewDidMount(viewArg: ViewMountArg) {
  console.log('ViewMountArg', viewArg);
  title.value = viewArg.view.title;
}

// 日历选择时间段出发的回调
// function handleDateSelect(arg: DateSelectArg) {
//   console.log("DateSelectArg", arg);
// }

// 点击事件对象的回调
async function handleEventClick(arg: EventClickArg) {
  console.log('EventClickArg', arg);
  if (confirm(`Are you sure you want to delete the event '${arg.event.title}'`)) {
    // 删除event
    await delEvent(arg.event.id);
    // 重新拉取events
    initEventList();
  }
}
// 组件实例对象
const calendar = ref<InstanceType<typeof FullCalendar> | null>(null);
// 底层的Calendar对象
let calendarApi: CalendarApi;

// 存储当前视口的宽度
const width = ref(innerWidth);
// 控制配置项抽屉状态的显示与隐藏
const drawerIsShow = ref(false);
// 使用计算属性 动态计算设置抽屉尺寸 视口区域小于1200px时 尺寸设置为300px 否则设置为当前窗口的30%
const drawerSize = computed(() => (width.value <= 1200 ? 300 : '30%'));
// 控制语言 locale 切换
const language = ref(true);

// 视图日期title
const title = ref('');

// 定义默认视图配置的选择项
const viewOptions = [
  {
    value: 'dayGridMonth',
    label: '月视图',
  },
  {
    value: 'dayGridWeek',
    label: '周视图',
  },
  {
    value: 'timeGridDay',
    label: '日视图',
  },
  {
    value: 'listWeek',
    label: '周程图',
  },
  {
    value: 'listDay',
    label: '日程图',
  },
];

onMounted(() => {
  // 通过getApi方法获得底层的Calendar对象 (从而就可以使用内置api)
  calendarApi = calendar.value!.getApi();
  initEventList();
});

async function initEventList() {
  const res = await getEventList();
  const events = res.map((item) => {
    return {
      id: item.id,
      title: item.title,
      backgroundColor: item.bgColor,
      start: timeFormat(new Date(item.startStr)),
      end: timeFormat(new Date(item.endStr)),
      groupId: item.groupId,
      meta: { ...item },
    };
  });

  // Object.assign(testCalendarStore.events, events);
  testCalendarStore.events = events;
}

// 监听窗口尺寸变化的事件回调
addEventListener('resize', () => {
  width.value = innerWidth;
});

// 改变日历视图
const handleClickChangeView = (view: string) => {
  calendarApi.changeView(view);
  title.value = calendarApi.view.title;
};

// 点击today按钮
const handleClickToday = () => {
  calendarApi.today();
  title.value = calendarApi.view.title;
};

// 点击前进按钮
const handleClickPrev = () => {
  calendarApi.prev();
  title.value = calendarApi.view.title;
};

// 点击后退按钮
const handleClickNext = () => {
  calendarApi.next();
  title.value = calendarApi.view.title;
};

// 监听配置项中的默认视图配置 initialView
watch(
  () => calendarOptions.initialView,
  () => {
    handleClickChangeView(calendarOptions.initialView as string);
  },
);

// 监听语言包切换的改变 顺便一同更新时区的设置
watch(language, () => {
  if (language.value) {
    calendarApi.setOption('locale', zhCN);
    calendarApi.setOption('timeZone', 'Asia/Shanghai');
  } else {
    calendarApi.setOption('locale', enGB);
    calendarApi.setOption('timeZone', 'UTC');
  }
});

watch(
  () => testCalendarStore.events,
  (n, o) => {
    console.log('events改变', n, o);
    calendarOptions.events = testCalendarStore.events;
  },
  // { immediate: true },
);

// 异步组件导入
const GroupForm = defineAsyncComponent(
  () => import('@/views/Test/modules/Calendar/components/GroupForm/index.vue'),
);
const EventForm = defineAsyncComponent(
  () => import('@/views/Test/modules/Calendar/components/EventForm/index.vue'),
);
// 控制动态组件显示
const currentFormIndex = ref(0);
// 动态组件的options
const forms = [
  { label: 'groupForm', value: GroupForm, title: '新建组' },
  { label: 'eventForm', value: EventForm, title: '新建日程' },
];

const handleClick = (operation: string) => {
  // 打开抽屉
  testCalendarStore.drawerIsShow = true;
  // 确认要显示的form组件
  currentFormIndex.value = forms.findIndex((item) => item.label === operation);
};
</script>

<script lang="ts">
export default {
  name: 'CalendarTestView',
};
</script>

<template>
  <!-- 配置项抽屉展示内容 -->
  <el-drawer v-model="drawerIsShow" title="日历配置单" :size="drawerSize">
    <div>
      <el-form
        label-position="left"
        label-width="100px"
        :model="calendarOptions"
        style="max-width: 460px"
      >
        <el-form-item label="显示年度周数">
          <el-switch
            v-model="calendarOptions.weekNumbers"
            inline-prompt
            active-text="是"
            inactive-text="否"
          />
        </el-form-item>
        <el-form-item label="显示周末">
          <el-switch
            v-model="calendarOptions.weekends"
            inline-prompt
            active-text="是"
            inactive-text="否"
          />
        </el-form-item>
        <el-form-item label="语言包">
          <el-switch v-model="language" inline-prompt active-text="中文" inactive-text="英语" />
        </el-form-item>
        <el-form-item label="选择视图">
          <el-select v-model="calendarOptions.initialView" clearable placeholder="Select">
            <el-option
              v-for="item in viewOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="开启可选">
          <el-switch
            v-model="calendarOptions.selectable"
            inline-prompt
            active-text="是"
            inactive-text="否"
          />
        </el-form-item>
      </el-form>
    </div>
  </el-drawer>

  <!-- 新建日程 or 编辑日程 -->
  <el-drawer v-model="testCalendarStore.drawerIsShow" :size="drawerSize">
    <template #header>
      <h4>{{ forms[currentFormIndex].title }}</h4>
    </template>
    <component :is="forms[currentFormIndex].value"></component>
  </el-drawer>

  <div class="h-[800px] w-[1000px]">
    <header class="flex h-[56px] items-center justify-between px-4">
      <!-- 左边部分 -->
      <div class="left flex items-center gap-2">
        <el-button link type="primary" @click="handleClickPrev">
          <el-icon :size="32"><ArrowLeft /></el-icon>
        </el-button>
        <el-button link type="primary" @click="handleClickNext">
          <el-icon :size="32"><ArrowRight /></el-icon>
        </el-button>
        <el-button type="primary" @click="handleClickToday">today</el-button>
      </div>
      <!-- 中间部分 -->
      <div class="flex flex-1 items-center justify-center">
        <h1>{{ title }}</h1>
      </div>
      <!-- 右边部分 -->
      <div class="flex items-center gap-4">
        <!-- <el-button-group>
          <el-button
            type="success"
            @click="handleClickChangeView('dayGridMonth')"
            >月视图</el-button
          >
          <el-button
            type="warning"
            @click="handleClickChangeView('dayGridWeek')"
            >周视图</el-button
          >
          <el-button type="danger" @click="handleClickChangeView('listWeek')"
            >日视图</el-button
          >
        </el-button-group> -->

        <el-button-group>
          <el-button type="success" @click="handleClick('groupForm')"> 新建组 </el-button>
          <el-button type="danger" @click="handleClick('eventForm')"> 新建日程 </el-button>
        </el-button-group>

        <div>
          <!-- <el-button circle type="primary">
            <el-icon><Plus /></el-icon>
          </el-button> -->
          <el-button circle type="default" @click="drawerIsShow = true">
            <el-icon><Setting /></el-icon>
          </el-button>
        </div>
      </div>
    </header>
    <FullCalendar ref="calendar" :options="calendarOptions">
      <template #eventContent="arg">
        <!-- <h1>{{ arg }}</h1> -->
        <b>{{ arg.timeText }}</b>
        <i>{{ arg.event.title }}</i>
      </template>
    </FullCalendar>
  </div>
</template>

<style scoped>
/* PC电脑端 */
@media screen and (width <= 1024px) {
}
</style>
